package  
{
	import com.bumpslide.events.DragEvent;
	import com.bumpslide.ui.Applet;
	import com.bumpslide.ui.behavior.DragBehavior;

	import flash.display.Sprite;
	import flash.events.Event;
	import flash.filters.BlurFilter;
	import flash.geom.Point;
	import flash.geom.Rectangle;

	/**
	 * Drag Example 4 - Drag and Toss
	 * 
	 * For this example, we are letting the dragBehavior move the drag target, but we
	 * are still listening for drag_move events so we can apply a motion blur
	 * using the velocity given to us by DragBehavior.
	 * 
	 * Then, when the ball is released (drag_stop), we start a custom animation that 
	 * continues to move the ball while applying friction to the velocity.
	 * 
	 * @author David Knape
	 * @mxmlc -sp+=../../classes -default-background-color 0xaaddaa  -default-frame-rate 60 
	 */
	public class DragExample04 extends Applet 
	{

		// a ball
		private var ball:Sprite;

		// size of the ball		
		private static const RADIUS:Number = 33;

		// ball's current velocity (given to us by DragBehavior)
		private var velocity:Point;	

		// the drag behavior control
		private var dragControl:DragBehavior;

		// our blur filter 
		private var blur:BlurFilter = new BlurFilter(0, 0, 3);

		
		override protected function addChildren():void
		{	
			createBall();
						
			// init drag behavior and save reference so we can
			// update drag bounds when stage size changes [see draw() method]
			dragControl = DragBehavior.init(ball, null, true);
			
			// listen for drag start and stop events
			addEventListener(DragEvent.EVENT_DRAG_START, handleDragStart);			addEventListener(DragEvent.EVENT_DRAG_MOVE, handleDragMove);
			addEventListener(DragEvent.EVENT_DRAG_STOP, handleDragStop);
		}

		
		override protected function draw():void
		{
			dragControl.dragBounds = new Rectangle(RADIUS, RADIUS, width - RADIUS * 2, height - RADIUS * 2);
			super.draw();
		}

		
		private function handleDragMove(event:DragEvent):void
		{
			velocity = event.velocity;
			applyMotionBlur();
		}

		
		/**
		 * On drag stop, start animating
		 */
		private function handleDragStop(event:DragEvent):void
		{
			velocity = event.velocity;
			addEventListener(Event.ENTER_FRAME, animate);
			animate();
		}

		
		/**
		 * On drag start, stop any pending animation
		 */
		private function handleDragStart(event:DragEvent):void
		{
			removeEventListener(Event.ENTER_FRAME, animate);
		}

		
		/**
		 * Create a ball
		 */
		private function createBall():void
		{
			ball = new Sprite();
			ball.buttonMode = true;
			
			with(ball.graphics) {
				lineStyle(0, 0, 0, true);
				beginFill(0x000088, .7);
				drawCircle(0, 0, RADIUS);
				endFill(); 
				// padding to keep filters from messing with our edges
				beginFill(0, 0);
				drawCircle(0, 0, RADIUS + 10);
				endFill();
			}
			ball.x = ball.y = 200;
			addChild(ball);
		}

		
		/**
		 * EnterFrame animation loop, runs after ball has been tossed
		 */
		private function animate(event:Event = null):void
		{
			// apply brakes
			velocity.x *= .95; 
			velocity.y *= .95;
			
			// update position
			ball.x += velocity.x;
			ball.y += velocity.y;
						
			// bounce
			if(ball.x < RADIUS) {
				ball.x = RADIUS;
				velocity.x *= -1;
			} else if (ball.x > width - RADIUS) {
				ball.x = width - RADIUS;
				velocity.x *= -1;
			}
			if(ball.y < RADIUS) {
				ball.y = RADIUS;
				velocity.y *= -1;
			} else if (ball.y > height - RADIUS) {
				ball.y = height - RADIUS;
				velocity.y *= -1;
			}
			
			// finish
			if(velocity.length < .5) {
				removeEventListener(Event.ENTER_FRAME, animate);
				velocity = new Point();
			}
			
			applyMotionBlur();
		}		

		
		private function applyMotionBlur():void
		{
			blur.blurX = velocity.x * .4;
			blur.blurY = velocity.y * .4;
			ball.filters = [blur];
		}
	}
}
